package cn.ljy.authority.service.impl;

import cn.ljy.authority.dao.mapper.*;
import cn.ljy.authority.model.SysPermission;
import cn.ljy.authority.model.SysRole;
import cn.ljy.authority.model.query.SysRoleQuery;
import cn.ljy.authority.model.query.SysUserQuery;
import cn.ljy.authority.service.SysRoleService;
import cn.ljy.common.exception.model.MyConfirmException;
import cn.ljy.common.exception.model.MyDataException;
import cn.ljy.common.exception.model.MyServiceException;
import cn.ljy.common.exception.model.MyWebException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

@Service
//@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.DEFAULT,timeout=36000,rollbackFor= MyRollBackException.class)
@Validated//表示开启sprint的校检框架，会自动扫描方法里的@Valid（@Valid注解一般写在接口即可）
@Slf4j
public class ISysRoleService extends IBaseService<SysRole, SysRoleQuery> implements SysRoleService {
    @Autowired
    private SysRoleMapper mapper;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private SysRolePermissionMapper sysRolePermissionMapper;
    @Autowired
    private SysPermissionMapper sysPermissionMapper;
    @Autowired
    private SysUserRoleMapper sysUserRoleMapper;

    /**
     * 是否是系统角色
     * 说明：系统角色不允许删除
     * @param sysRole
     * @return true表示是系统角色
     */
    private boolean isSystemRole(SysRole sysRole){
        boolean result=false;
        if(sysRole.getId()<=0){
            result=true;
        }
        return result;
    }

    @Override
    public void afterFindAll(List<SysRole> list) {
        for(SysRole role:list){
            //添加相关关联属性
            //账户数量
            SysUserQuery sysUserQuery=new SysUserQuery();
            sysUserQuery.setRoleId(Integer.valueOf(role.getId().toString()));
            int userNumber=sysUserMapper.count(sysUserQuery);
            role.setUserNumber(userNumber);
            //权限/菜单数
            role.setPermissionumber(sysRolePermissionMapper.countAllPermissionByRoleId(role.getId()));
        }
    }

    @Override
    protected void beforeGet(Serializable id) {

    }


    @Override
    protected void beforeUpdate(SysRole sysRole) {
        if(sysRole.getId()==null){
            throw new MyWebException("编辑失败：id不能为空");
        }
    }

    @Override
    protected void beforeSave(SysRole sysRole) {

    }

    @Override
    protected void beforeDelete(Serializable[] ids) {
        /*if(ids.length==0){
            throw new MyWebException("操作失败：请选择要移除的角色");
        }*/
        //获取角色和账户关系的错误信息集合
        Map<String,Integer> errorMessageMapOfUserRole=new HashMap();
        for(Serializable id:ids){
            SysRole sysRole=mapper.findById(id);
            if(sysRole!=null){
                if(this.isSystemRole(sysRole)){
                    throw new MyServiceException("角色删除失败："+sysRole.getName()+"是系统固定角色，不允许删除");
                }
                //获取该角色拥有的账户数量
                SysUserQuery sysUserQuery=new SysUserQuery();
                sysUserQuery.setRoleId(Integer.valueOf(id.toString()));
                int userNumber=sysUserMapper.count(sysUserQuery);
                if(userNumber>0){
                    errorMessageMapOfUserRole.put(sysRole.getName(),userNumber);
                }
            }
        }
        //定义错误信息
        StringBuilder errorMessage=new StringBuilder();
        if(errorMessageMapOfUserRole.size()>0){
            int index=0;//索引
            errorMessage.append("角色删除失败:");
            //循环处理错误信息
            for(String roleName:errorMessageMapOfUserRole.keySet()){
                errorMessage.append("角色"+roleName+"有"+errorMessageMapOfUserRole.get(roleName)+"个账户使用");
                if(index==errorMessageMapOfUserRole.size()-1){//最后一个不进行处理，是为了交给前端来决定最后一句话的符号结尾。
//                    errorMessage.append("。");
                }else{
                    errorMessage.append("，");
                }
                index++;
            }
            throw new MyConfirmException(errorMessage.toString());
        }
        //移除角色和权限关系
        sysRolePermissionMapper.deleteByRoleIds(ids);
    }

    @Override
    protected void beforeForceDelete(Serializable[] ids) {
        for(Serializable id:ids){
            SysRole sysRole=mapper.findById(id);
            if(sysRole!=null){
                if(this.isSystemRole(sysRole)){
                    throw new MyServiceException("角色删除失败：系统固定角色不允许删除");
                }
                //移除该角色拥有的账户集合
                sysUserRoleMapper.removeAllUserByRoleId(id);
            }
        }
        //移除角色和权限关系
        sysRolePermissionMapper.deleteByRoleIds(ids);
    }

    @Override
    public void updateEnabledByIdIn(Serializable[] ids, Boolean enabled) {
        mapper.updateEnabledByIdIn(ids,enabled);
    }

    @Override
    public void updateRolePermission(@NotNull Integer roleId, @NotNull Set<Long> permissionIds) {
        //检查权限是否存在：如果并发度高可以减掉该步骤，由数据库外键去验证
        permissionIds.stream().forEach(permissionId->{
            SysPermission permission=sysPermissionMapper.findById(permissionId);
            if(permission==null){
                throw new MyDataException("编辑失败：权限("+permission.getName()+")已移除");
            }
        });
        //移除该角色原有的权限
        sysRolePermissionMapper.deleteByRoleIds(new Integer[]{roleId});
        //重复新的权限
        sysRolePermissionMapper.saveByRoleIdAndPermissionIds(roleId,permissionIds.stream().mapToLong(i->i).toArray());
    }

    @Override
    public List<Long> getPermissionIdsByRoleId(@NotNull Integer roleId) {
        return sysRolePermissionMapper.getPermissionIdsByRoleId(roleId);
    }
}
